#ifndef __SMQTT_H__
#define __SMQTT_H__

#ifdef __cplusplus
extern "C" {
#endif
// 类型定义
typedef char i8;
typedef short i16;
typedef int i32;
typedef long i64;

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;

typedef float f32;
typedef double f64;

// 函数接口
#include <stdlib.h>
#define mqtt_malloc(size) malloc(size)
#define mqtt_free(ptr) free(ptr)
#include <string.h>
#define mqtt_strlen(str) strlen(str)
#define mqtt_memcpy(dest,src,n) memcpy(dest,src,n)
#define mqtt_memset(src,c,n) memset(src,c,n)

// 函数参数标记
#ifndef _IN
#define _IN
#endif

#ifndef _OUT
#define _OUT
#endif

#ifndef _INOUT
#define _INOUT
#endif

// 协议包类型
typedef enum mqtt_pack_type {
	mqtt_connect,
	mqtt_connack,
	mqtt_publish,
	mqtt_puback,
	mqtt_pubrec,
	mqtt_pubrel,
	mqtt_pubcomp,
	mqtt_subscribe,
	mqtt_suback,
	mqtt_unsubscribe,
	mqtt_unsuback,
	mqtt_pingreq,
	mqtt_pingresp,
	mqtt_disconnect,
	mqtt_unknow,
}mqtt_pack_type;


extern u8 *mqtt_connect_packet(
	_IN const u8 *client_id,
	_IN const u8 *username,
	_IN const u8 *password,
	_IN const u16 alive_time,
	_IN const u8 clean_session,
	_OUT u64 *pack_len);

static const u8 mqtt_connack_packet[4] = { 0x20, 0x02 ,0x00,0x00 };
#define mqtt_connack_packet_len (sizeof(mqtt_connack_packet))

static const u8 mqtt_pingreq_packet[2] = { 0xc0,0x00 };
#define mqtt_pingreq_packet_len (sizeof(mqtt_pingreq_packet))
static const u8 mqtt_pingresp_packet[2] = { 0xd0,0x00 };
#define mqtt_pingresp_packet_len (sizeof(mqtt_pingresp_packet))

static const u8 mqtt_disconnect_packet[2] = { 0xe0,0x00 };
#define mqtt_disconnect_packet_len (sizeof(mqtt_disconnect_packet))


extern u8 *mqtt_publish_packet(
	_IN const u8 qos,
	_IN const u8 *topic,
	_IN const u8 *data,
	_OUT u64 *pack_len,
	_IN u16 seq,
	_IN u8 dup,
	_IN u8 retain);

// qos1 publish ack
#define mqtt_puback_packet_len 4
extern void mqtt_puback_packet(_OUT u8 *u8_4_buf, _IN u16 seq);
// qos2 publish
#define mqtt_pubrec_packet_len 4
extern void mqtt_pubrec_packet(_OUT u8 *u8_4_buf, _IN u16 seq);
#define mqtt_pubrel_packet_len 6
extern void mqtt_pubrel_packet(_OUT u8 *u8_6_buf, _IN u16 seq);
#define mqtt_pubcomp_packet_len 4
extern void mqtt_pubcomp_packet(_OUT u8 *u8_4_buf, _IN u16 seq);


extern u8 *mqtt_subscribe_packet(
	_IN u8 **topics,
	_IN u8 *qoss,
	_IN u64 topics_len,
	_OUT u64 *pack_len,
	_IN u16 seq);
extern u8 *mqtt_suback_packet(
	_IN u8 *qoss,
	_IN u64 len,
	_OUT u64 *pack_len,
	_IN u16 seq);

extern u8 *mqtt_unsubscribe_packet(
	_IN u8 **topics,
	_IN u64 topics_len,
	_OUT u64 *pack_len,
	_IN u16 seq);
#define mqtt_unsuback_packet_len 4
extern void mqtt_unsuback_packet(
	_OUT u8 *u8_4_buf,
	_IN u16 seq);


extern void mqtt_unpacket_type(
	_IN u8 head,
	_OUT mqtt_pack_type *type);

extern u32 mqtt_decode_remaining_len(_IN const u8 *buffer, _OUT u8 *len_level);

typedef struct mqtt_publish_data_st
{
	u8 dup;
	u8 qos;
	u8 retain;
	u16 topic_len;
	u8 *topic;
	u16 seq;
	u8 *data;
}mqtt_publish_data_t;


extern void mqtt_unpacket_publish_data(
	_IN u8 head,
	_IN u32 payload_len,
	_IN const u8 *payload_buf,
	_OUT mqtt_publish_data_t *detail);


#ifdef __cplusplus
}
#endif

#endif